package com.boot2.core.concurrent;


import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangweilin
 * @Description: 队列同步器，即需要同步的资源，会自动在挂起中排队等待，轮流被执行时，
 * 也是逐个逐个的出来，出来的条件是释放锁，释放有显示释放，也有超时释放
 * @date 2020/8/10
 */
public class QueueSync extends Semaphore {

    /**
     * 定时任务线程池
     */
    private static ScheduledThreadPoolExecutor scheduledExecutorService = new ScheduledThreadPoolExecutor(50);

    private int permits;

    private ScheduledFuture<?> scheduledFuture;

    public QueueSync(int permits) {
        super(permits);
        this.permits = permits;
    }

    public QueueSync(int permits, boolean fair) {
        super(permits, fair);
        this.permits = permits;
    }



    /**
     * 带超时功能的锁
     *
     * @param time
     * @param timeUnit
     * @throws InterruptedException
     */
    public void acquire(Long time, TimeUnit timeUnit) throws InterruptedException {
        super.acquire();
        scheduledFuture = scheduledExecutorService.schedule(new ChannelSyncTask(this), time, timeUnit);
    }

    static class ChannelSyncTask implements Runnable {
        private QueueSync queueSync;

        public ChannelSyncTask(QueueSync queueSync) {
            this.queueSync = queueSync;
        }

        @Override
        public void run() {
            queueSync.release();
        }
    }

    public void releaseAndCancel() {
        if(scheduledFuture!=null && !scheduledFuture.isDone()) {
            scheduledFuture.cancel(true);
        }
        super.release();
    }
}
